home *** CD-ROM | disk | FTP | other *** search
/ Whiteline: Alpha / Whiteline Alpha.iso / linux / atari / source / source.lzh / atari-linux-0.01pl3 / fs / minix / inode.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-06-05  |  11.5 KB  |  485 lines

  1. /*
  2.  *  linux/fs/minix/inode.c
  3.  *
  4.  *  Copyright (C) 1991, 1992  Linus Torvalds
  5.  *
  6.  * This file is subject to the terms and conditions of the GNU General Public
  7.  * License.  See the file README.legal in the main directory of this archive
  8.  * for more details.
  9.  */
  10.  
  11. #include <linux/sched.h>
  12. #include <linux/minix_fs.h>
  13. #include <linux/kernel.h>
  14. #include <linux/mm.h>
  15. #include <linux/string.h>
  16. #include <linux/stat.h>
  17. #include <linux/locks.h>
  18.  
  19. #include <asm/system.h>
  20. #include <asm/segment.h>
  21. #include <asm/bitops.h>
  22.  
  23. void minix_put_inode(struct inode *inode)
  24. {
  25.     if (inode->i_nlink)
  26.         return;
  27.     inode->i_size = 0;
  28.     minix_truncate(inode);
  29.     minix_free_inode(inode);
  30. }
  31.  
  32. void minix_put_super(struct super_block *sb)
  33. {
  34.     int i;
  35.  
  36.     lock_super(sb);
  37.     sb->s_dev = 0;
  38.     for(i = 0 ; i < MINIX_I_MAP_SLOTS ; i++)
  39.         brelse(sb->u.minix_sb.s_imap[i]);
  40.     for(i = 0 ; i < MINIX_Z_MAP_SLOTS ; i++)
  41.         brelse(sb->u.minix_sb.s_zmap[i]);
  42.     unlock_super(sb);
  43.     return;
  44. }
  45.  
  46. static struct super_operations minix_sops = {
  47.     minix_read_inode,
  48.     NULL,
  49.     minix_write_inode,
  50.     minix_put_inode,
  51.     minix_put_super,
  52.     NULL,
  53.     minix_statfs,
  54.     NULL
  55. };
  56.  
  57. #ifdef __mc68000__
  58. #define BIT(bit) ((bit) ^ 15)
  59. #else
  60. #define BIT(bit) (bit)
  61. #endif
  62.  
  63. struct super_block *minix_read_super(struct super_block *s,void *data,
  64.                      int silent)
  65. {
  66.     struct buffer_head *bh;
  67.     struct minix_super_block *ms;
  68.     unsigned int i;
  69.     int dev=s->s_dev,block;
  70.  
  71.     if (32 != sizeof (struct minix_inode))
  72.         panic("bad i-node size");
  73.     lock_super(s);
  74.     if (!(bh = bread(dev,1,BLOCK_SIZE))) {
  75.         s->s_dev=0;
  76.         unlock_super(s);
  77.         printk("MINIX-fs: unable to read superblock\n");
  78.         return NULL;
  79.     }
  80.     ms = (struct minix_super_block *) bh->b_data;
  81.     s->s_blocksize = 1024;
  82.     s->s_blocksize_bits = 10;
  83.     s->u.minix_sb.s_ninodes = ms->s_ninodes;
  84.     s->u.minix_sb.s_nzones = ms->s_nzones;
  85.     s->u.minix_sb.s_imap_blocks = ms->s_imap_blocks;
  86.     s->u.minix_sb.s_zmap_blocks = ms->s_zmap_blocks;
  87.     s->u.minix_sb.s_firstdatazone = ms->s_firstdatazone;
  88.     s->u.minix_sb.s_log_zone_size = ms->s_log_zone_size;
  89.     s->u.minix_sb.s_max_size = ms->s_max_size;
  90.     s->s_magic = ms->s_magic;
  91.     brelse(bh);
  92.     if (s->s_magic == MINIX_SUPER_MAGIC) {
  93.         s->u.minix_sb.s_dirsize = 16;
  94.         s->u.minix_sb.s_namelen = 14;
  95.     } else if (s->s_magic == MINIX_SUPER_MAGIC2) {
  96.         s->u.minix_sb.s_dirsize = 32;
  97.         s->u.minix_sb.s_namelen = 30;
  98.     } else {
  99.         s->s_dev = 0;
  100.         unlock_super(s);
  101.         if (!silent)
  102.             printk("VFS: Can't find a minix filesystem on dev 0x%04x.\n",
  103.                    dev);
  104.         return NULL;
  105.     }
  106.     for (i=0;i < MINIX_I_MAP_SLOTS;i++)
  107.         s->u.minix_sb.s_imap[i] = NULL;
  108.     for (i=0;i < MINIX_Z_MAP_SLOTS;i++)
  109.         s->u.minix_sb.s_zmap[i] = NULL;
  110.     block=2;
  111.     for (i=0 ; i < s->u.minix_sb.s_imap_blocks ; i++)
  112.         if ((s->u.minix_sb.s_imap[i]=bread(dev,block,BLOCK_SIZE)) != NULL)
  113.             block++;
  114.         else
  115.             break;
  116.     for (i=0 ; i < s->u.minix_sb.s_zmap_blocks ; i++)
  117.         if ((s->u.minix_sb.s_zmap[i]=bread(dev,block,BLOCK_SIZE)) != NULL)
  118.             block++;
  119.         else
  120.             break;
  121.     if (block != 2+s->u.minix_sb.s_imap_blocks+s->u.minix_sb.s_zmap_blocks) {
  122.         for(i=0;i<MINIX_I_MAP_SLOTS;i++)
  123.             brelse(s->u.minix_sb.s_imap[i]);
  124.         for(i=0;i<MINIX_Z_MAP_SLOTS;i++)
  125.             brelse(s->u.minix_sb.s_zmap[i]);
  126.         s->s_dev=0;
  127.         unlock_super(s);
  128.         printk("MINIX-fs: bad superblock or unable to read bitmaps\n");
  129.         return NULL;
  130.     }
  131.     set_bit(BIT(0),s->u.minix_sb.s_imap[0]->b_data);
  132.     set_bit(BIT(0),s->u.minix_sb.s_zmap[0]->b_data);
  133.     /* set up enough so that it can read an inode */
  134.     s->s_dev = dev;
  135.     s->s_op = &minix_sops;
  136.     s->s_mounted = iget(s,MINIX_ROOT_INO);
  137.     unlock_super(s);
  138.     if (!s->s_mounted) {
  139.         s->s_dev = 0;
  140.         printk("MINIX-fs: get root inode failed\n");
  141.         return NULL;
  142.     }
  143.     return s;
  144. }
  145.  
  146. void minix_statfs(struct super_block *sb, struct statfs *buf)
  147. {
  148.     long tmp;
  149.  
  150.     put_fs_long(MINIX_SUPER_MAGIC, &buf->f_type);
  151.     put_fs_long(1024, &buf->f_bsize);
  152.     tmp = sb->u.minix_sb.s_nzones - sb->u.minix_sb.s_firstdatazone;
  153.     tmp <<= sb->u.minix_sb.s_log_zone_size;
  154.     put_fs_long(tmp, &buf->f_blocks);
  155.     tmp = minix_count_free_blocks(sb);
  156.     put_fs_long(tmp, &buf->f_bfree);
  157.     put_fs_long(tmp, &buf->f_bavail);
  158.     put_fs_long(sb->u.minix_sb.s_ninodes, &buf->f_files);
  159.     put_fs_long(minix_count_free_inodes(sb), &buf->f_ffree);
  160.     put_fs_long(sb->u.minix_sb.s_namelen, &buf->f_namelen);
  161.     /* Don't know what value to put in buf->f_fsid */
  162. }
  163.  
  164. #define inode_bmap(inode,nr) ((inode)->u.minix_i.i_data[(nr)])
  165.  
  166. static int block_bmap(struct buffer_head * bh, int nr)
  167. {
  168.     int tmp;
  169.  
  170.     if (!bh)
  171.         return 0;
  172.     tmp = ((unsigned short *) bh->b_data)[nr];
  173.     brelse(bh);
  174.     return tmp;
  175. }
  176.  
  177. int minix_bmap(struct inode * inode,int block)
  178. {
  179.     int i;
  180.  
  181.     if (block<0) {
  182.         printk("minix_bmap: block<0");
  183.         return 0;
  184.     }
  185.     if (block >= 7+512+512*512) {
  186.         printk("minix_bmap: block>big");
  187.         return 0;
  188.     }
  189.     if (block < 7)
  190.         return inode_bmap(inode,block);
  191.     block -= 7;
  192.     if (block < 512) {
  193.         i = inode_bmap(inode,7);
  194.         if (!i)
  195.             return 0;
  196.         return block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),block);
  197.     }
  198.     block -= 512;
  199.     i = inode_bmap(inode,8);
  200.     if (!i)
  201.         return 0;
  202.     i = block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),block>>9);
  203.     if (!i)
  204.         return 0;
  205.     return block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),block & 511);
  206. }
  207.  
  208. static struct buffer_head * inode_getblk(struct inode * inode, int nr, int create)
  209. {
  210.     int tmp;
  211.     unsigned short *p;
  212.     struct buffer_head * result;
  213.  
  214.     p = inode->u.minix_i.i_data + nr;
  215. repeat:
  216.     tmp = *p;
  217.     if (tmp) {
  218.         result = getblk(inode->i_dev, tmp, BLOCK_SIZE);
  219.         if (tmp == *p)
  220.             return result;
  221.         brelse(result);
  222.         goto repeat;
  223.     }
  224.     if (!create)
  225.         return NULL;
  226.     tmp = minix_new_block(inode->i_sb);
  227.     if (!tmp)
  228.         return NULL;
  229.     result = getblk(inode->i_dev, tmp, BLOCK_SIZE);
  230.     if (*p) {
  231.         minix_free_block(inode->i_sb,tmp);
  232.         brelse(result);
  233.         goto repeat;
  234.     }
  235.     *p = tmp;
  236.     inode->i_ctime = CURRENT_TIME;
  237.     inode->i_dirt = 1;
  238.     return result;
  239. }
  240.  
  241. static struct buffer_head * block_getblk(struct inode * inode,
  242.     struct buffer_head * bh, int nr, int create)
  243. {
  244.     int tmp;
  245.     unsigned short *p;
  246.     struct buffer_head * result;
  247.  
  248.     if (!bh)
  249.         return NULL;
  250.     if (!bh->b_uptodate) {
  251.         ll_rw_block(READ, 1, &bh);
  252.         wait_on_buffer(bh);
  253.         if (!bh->b_uptodate) {
  254.             brelse(bh);
  255.             return NULL;
  256.         }
  257.     }
  258.     p = nr + (unsigned short *) bh->b_data;
  259. repeat:
  260.     tmp = *p;
  261.     if (tmp) {
  262.         result = getblk(bh->b_dev, tmp, BLOCK_SIZE);
  263.         if (tmp == *p) {
  264.             brelse(bh);
  265.             return result;
  266.         }
  267.         brelse(result);
  268.         goto repeat;
  269.     }
  270.     if (!create) {
  271.         brelse(bh);
  272.         return NULL;
  273.     }
  274.     tmp = minix_new_block(inode->i_sb);
  275.     if (!tmp) {
  276.         brelse(bh);
  277.         return NULL;
  278.     }
  279.     result = getblk(bh->b_dev, tmp, BLOCK_SIZE);
  280.     if (*p) {
  281.         minix_free_block(inode->i_sb,tmp);
  282.         brelse(result);
  283.         goto repeat;
  284.     }
  285.     *p = tmp;
  286.     bh->b_dirt = 1;
  287.     brelse(bh);
  288.     return result;
  289. }
  290.  
  291. struct buffer_head * minix_getblk(struct inode * inode, int block, int create)
  292. {
  293.     struct buffer_head * bh;
  294.  
  295.     if (block<0) {
  296.         printk("minix_getblk: block<0");
  297.         return NULL;
  298.     }
  299.     if (block >= 7+512+512*512) {
  300.         printk("minix_getblk: block>big");
  301.         return NULL;
  302.     }
  303.     if (block < 7)
  304.         return inode_getblk(inode,block,create);
  305.     block -= 7;
  306.     if (block < 512) {
  307.         bh = inode_getblk(inode,7,create);
  308.         return block_getblk(inode, bh, block, create);
  309.     }
  310.     block -= 512;
  311.     bh = inode_getblk(inode,8,create);
  312.     bh = block_getblk(inode, bh, block>>9, create);
  313.     return block_getblk(inode, bh, block & 511, create);
  314. }
  315.  
  316. struct buffer_head * minix_bread(struct inode * inode, int block, int create)
  317. {
  318.     struct buffer_head * bh;
  319.  
  320.     bh = minix_getblk(inode,block,create);
  321.     if (!bh || bh->b_uptodate)
  322.         return bh;
  323.     ll_rw_block(READ, 1, &bh);
  324.     wait_on_buffer(bh);
  325.     if (bh->b_uptodate)
  326.         return bh;
  327.     brelse(bh);
  328.     return NULL;
  329. }
  330.  
  331. void minix_read_inode(struct inode * inode)
  332. {
  333.     struct buffer_head * bh;
  334.     struct minix_inode * raw_inode;
  335.     int block, ino;
  336.  
  337.     ino = inode->i_ino;
  338.     inode->i_op = NULL;
  339.     inode->i_mode = 0;
  340.     if (!ino || (ulong)ino >= inode->i_sb->u.minix_sb.s_ninodes) {
  341.         printk("Bad inode number on dev 0x%04x: %d is out of range\n",
  342.             inode->i_dev, ino);
  343.         return;
  344.     }
  345.     block = 2 + inode->i_sb->u.minix_sb.s_imap_blocks +
  346.             inode->i_sb->u.minix_sb.s_zmap_blocks +
  347.             (ino-1)/MINIX_INODES_PER_BLOCK;
  348.     if (!(bh=bread(inode->i_dev,block, BLOCK_SIZE))) {
  349.         printk("Major problem: unable to read inode from dev 0x%04x\n",
  350.             inode->i_dev);
  351.         return;
  352.     }
  353.     raw_inode = ((struct minix_inode *) bh->b_data) +
  354.             (ino-1)%MINIX_INODES_PER_BLOCK;
  355.     inode->i_mode = raw_inode->i_mode;
  356.     inode->i_uid = raw_inode->i_uid;
  357.     inode->i_gid = raw_inode->i_gid;
  358.     inode->i_nlink = raw_inode->i_nlinks;
  359.     inode->i_size = raw_inode->i_size;
  360.     inode->i_mtime = inode->i_atime = inode->i_ctime = raw_inode->i_time;
  361.     inode->i_blocks = inode->i_blksize = 0;
  362.     if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
  363.         inode->i_rdev = raw_inode->i_zone[0];
  364.     else for (block = 0; block < 9; block++)
  365.         inode->u.minix_i.i_data[block] = raw_inode->i_zone[block];
  366.     brelse(bh);
  367.     if (S_ISREG(inode->i_mode))
  368.         inode->i_op = &minix_file_inode_operations;
  369.     else if (S_ISDIR(inode->i_mode))
  370.         inode->i_op = &minix_dir_inode_operations;
  371.     else if (S_ISLNK(inode->i_mode))
  372.         inode->i_op = &minix_symlink_inode_operations;
  373.     else if (S_ISCHR(inode->i_mode))
  374.         inode->i_op = &chrdev_inode_operations;
  375.     else if (S_ISBLK(inode->i_mode))
  376.         inode->i_op = &blkdev_inode_operations;
  377.     else if (S_ISFIFO(inode->i_mode))
  378.         init_fifo(inode);
  379. }
  380.  
  381. static struct buffer_head * minix_update_inode(struct inode * inode)
  382. {
  383.     struct buffer_head * bh;
  384.     struct minix_inode * raw_inode;
  385.     int ino, block;
  386.  
  387.     ino = inode->i_ino;
  388.     if (!ino || (ulong)ino >= inode->i_sb->u.minix_sb.s_ninodes) {
  389.         printk("Bad inode number on dev 0x%04x: %d is out of range\n",
  390.             inode->i_dev, ino);
  391.         inode->i_dirt = 0;
  392.         return 0;
  393.     }
  394.     block = 2 + inode->i_sb->u.minix_sb.s_imap_blocks + inode->i_sb->u.minix_sb.s_zmap_blocks +
  395.         (ino-1)/MINIX_INODES_PER_BLOCK;
  396.     if (!(bh=bread(inode->i_dev, block, BLOCK_SIZE))) {
  397.         printk("unable to read i-node block\n");
  398.         inode->i_dirt = 0;
  399.         return 0;
  400.     }
  401.     raw_inode = ((struct minix_inode *)bh->b_data) +
  402.         (ino-1)%MINIX_INODES_PER_BLOCK;
  403.     raw_inode->i_mode = inode->i_mode;
  404.     raw_inode->i_uid = inode->i_uid;
  405.     raw_inode->i_gid = inode->i_gid;
  406.     raw_inode->i_nlinks = inode->i_nlink;
  407.     raw_inode->i_size = inode->i_size;
  408.     raw_inode->i_time = inode->i_mtime;
  409.     if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
  410.         raw_inode->i_zone[0] = inode->i_rdev;
  411.     else for (block = 0; block < 9; block++)
  412.         raw_inode->i_zone[block] = inode->u.minix_i.i_data[block];
  413.     inode->i_dirt=0;
  414.     bh->b_dirt=1;
  415.     return bh;
  416. }
  417.  
  418. void minix_write_inode(struct inode * inode)
  419. {
  420.     struct buffer_head *bh;
  421.     bh = minix_update_inode(inode);
  422.     brelse(bh);
  423. }
  424.  
  425. static struct buffer_head *
  426. minix_clear_link (struct inode *inode)
  427. {
  428.   struct buffer_head *bh;
  429.   struct minix_inode *raw_inode;
  430.   int ino, block;
  431.  
  432.   ino = inode->i_ino;
  433.   if (!ino || (ulong) ino >= inode->i_sb->u.minix_sb.s_ninodes)
  434.     {
  435.       printk ("Bad inode number on dev 0x%04x: %d is out of range\n",
  436.           inode->i_dev, ino);
  437.       return 0;
  438.     }
  439.   block = (2 + inode->i_sb->u.minix_sb.s_imap_blocks
  440.        + inode->i_sb->u.minix_sb.s_zmap_blocks +
  441.        (ino - 1) / MINIX_INODES_PER_BLOCK);
  442.   bh = bread (inode->i_dev, block, BLOCK_SIZE);
  443.   if (!bh)
  444.     {
  445.       printk ("unable to read i-node block\n");
  446.       return 0;
  447.     }
  448.   raw_inode = ((struct minix_inode *) bh->b_data
  449.            + (ino - 1) % MINIX_INODES_PER_BLOCK);
  450.   raw_inode->i_nlinks = 0;
  451.   bh->b_dirt = 1;
  452.   return bh;
  453. }
  454.  
  455. void
  456. minix_clear_inode (struct inode *inode)
  457. {
  458.   struct buffer_head *bh;
  459.   bh = minix_clear_link (inode);
  460.   brelse (bh);
  461. }
  462.  
  463. int minix_sync_inode(struct inode * inode)
  464. {
  465.     int err = 0;
  466.     struct buffer_head *bh;
  467.  
  468.     bh = minix_update_inode(inode);
  469.     if (bh && bh->b_dirt)
  470.     {
  471.         ll_rw_block(WRITE, 1, &bh);
  472.         wait_on_buffer(bh);
  473.         if (bh->b_req && !bh->b_uptodate)
  474.         {
  475.             printk ("IO error syncing minix inode [%04x:%08lu]\n",
  476.                 inode->i_dev, inode->i_ino);
  477.             err = -1;
  478.         }
  479.     }
  480.     else if (!bh)
  481.         err = -1;
  482.     brelse (bh);
  483.     return err;
  484. }
  485.